/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controller;

import java.util.ArrayList;

/**
 *
 * @author Administrador
 */
public class LogicaGame {


    /*
     * paresRegion() dada una region, devuelvo todos los pares (i,j) 
     * que la componen en un arraylist. No son PARES explicitamente, las filas estan en las posiciones
     * pares del arraylist y las columnas en las impares
    */

    public static ArrayList<Integer> paresRegion(int region){
	int limInfX = 0;
        int limInfY = 0;
        int limSupX = 0;
        int limSupY = 0;
        
        ArrayList <Integer> res = new ArrayList<Integer>();
	switch(region) {
 		case 1: limInfX = 0; limInfY = 0; limSupX = 2; limSupY = 2; break;
 		case 2: limInfX = 0; limInfY = 3; limSupX = 2; limSupY = 5; break;
		case 3: limInfX = 0; limInfY = 6; limSupX = 2; limSupY = 8; break;
		case 4: limInfX = 3; limInfY = 0; limSupX = 5; limSupY = 2; break;
		case 5: limInfX = 3; limInfY = 3; limSupX = 5; limSupY = 5; break;
		case 6: limInfX = 3; limInfY = 6; limSupX = 5; limSupY = 8; break;
		case 7: limInfX = 6; limInfY = 0; limSupX = 8; limSupY = 2; break;
		case 8: limInfX = 6; limInfY = 3; limSupX = 8; limSupY = 5; break;
		case 9: limInfX = 6; limInfY = 6; limSupX = 8; limSupY = 8; break;
	}
    
        for(int i=limInfX; i<=limSupX; i++){
		for(int j=limInfY; j<=limSupY; j++){
                    res.add(i);
                    res.add(j);
		}
	}
	return res;
}

 /*
 * Region() dado un par (fila x, columna y), devuelvo su region 
 */

   public static int region(int x, int y){
	boolean region1 = (((x>=0) && (x<=2)) && ((y>=0) && (y<=2)));
	boolean region2 = (((x>=0) && (x<=2)) && ((y>=3) && (y<=5)));
	boolean region3 = (((x>=0) && (x<=2)) && ((y>=6) && (y<=8)));
        boolean region4 = (((x>=3) && (x<=5)) && ((y>=0) && (y<=2)));
	boolean region5 = (((x>=3) && (x<=5)) && ((y>=3) && (y<=5)));
	boolean region6 = (((x>=3) && (x<=5)) && ((y>=6) && (y<=8)));
        boolean region7 = (((x>=6) && (x<=8)) && ((y>=0) && (y<=2)));
	boolean region8 = (((x>=6) && (x<=8)) && ((y>=3) && (y<=5)));
	if (region1) {
           return 1;
        }
         else
            if (region2) {
                return 2;
            }
             else
                if (region3) {
                    return 3;
                }
                 else
                    if (region4) {
                        return 4;
                    }
                     else
                        if (region5) {
                            return 5;
                        }
                         else
                            if (region6) {
                                return 6;
                            }
                             else 
                                if (region7) {
                                    return 7;
                                }
                                 else
                                    if (region8) {
                                        return 8;
                                    }        
                                     else {
                                        return 9;
                                     }
    }
 
 /*
 * paresFila() dada una fila, devuelve todos los pares que la componen en un arraylist 
 * No son PARES explicitamente, las filas estan en las posiciones
 * pares del arraylist y las columnas en las impares
 */
   
   public static ArrayList<Integer> paresFila(int fila){
       ArrayList<Integer> res = new ArrayList<Integer>();
       for(int j=0; j<=8; j++){
           res.add(fila);
           res.add(j);
       }
       return res;
   }
   
 /*
 * paresColumna() dada una columna, devuelve todos los pares que la componen en un arraylist 
 * No son PARES explicitamente, las filas estan en las posiciones
 * pares del arraylist y las columnas en las impares
 */
   
   public static ArrayList<Integer> paresColumna(int columna){
       ArrayList<Integer> res = new ArrayList<Integer>();
       for(int i=0; i<=8; i++){
           res.add(i);
           res.add(columna);
       }
       return res;
   }
   
   /*
    * observar() dado un par cualquiera, conjuga en un solo arraylist 
    * los pares devueltos por paresRegion, paresFila y paresColumna
    * Filas en posiciones pares y columnas en posiciones impares del arraylist devuelvo
    */
   
   public static ArrayList<Integer> observar(int fila, int columna){
       ArrayList<Integer> res = paresRegion(region(fila,columna));
       ArrayList<Integer> aux = paresFila(fila);
       for(int i=0; i<aux.size(); i++){
           res.add(aux.get(i));
       }
       aux = paresColumna(columna);
       for(int i=0; i<aux.size(); i++){
           res.add(aux.get(i));
       }
       return res;
   }
   
   /*
    * completa() dada una matriz de 9X9, devuelve TRUE sii 
    * todos sus numeros son distintos de cero.
    *
    */
   
   public static boolean completa(int [][] matriz){
       for(int i=0; i<9; i++){
            for(int j=0; j<9; j++){
                if(matriz[i][j] == 0){
                    return false;
                }
            }
       }
       return true;
   }
   
   /*
    * esSolucion() dada la matriz, una casilla y un numero, devuelve TRUE sii 
    * el numero puede ir en la casilla respetando las reglas
    * del juego.
    */
   
   public static boolean esSolucion(int [][] matriz, int fila, int columna, int numero){
       ArrayList<Integer> aux = observar(fila,columna);
       for(int i=0; i<aux.size(); i = i+2){
           if(matriz[aux.get(i)][aux.get(i+1)] == numero){ // aux.get(i) -> FILA, aux.get(i+1) -> COLUMNA
                return false;
           }    
       }
       return true;
   }
   
   /*
    * soluciones() dada la matriz y una casilla, voy a retornar un arraylist 
    * con aquellos numeros que pueden ir en la casilla (invoca a esSolucion, y los
    * va almacenando en el arraylist)
    */
   
   public static ArrayList<Integer> soluciones(int [][] matriz, int fila, int columna){
       ArrayList<Integer> res = new ArrayList<Integer>();
       for(int i=1; i<=9; i++){
           if (esSolucion(matriz, fila, columna, i)){
               res.add(i);
           }
       }
       return res;
   }
   
   /*
    * solucionarMatriz() dada la matriz, soluciona el Sudoku
    */
   
   public static int[][] solucionarMatriz(int [][] matriz){
       ArrayList<Integer> solution;
       int [][] aux = matriz;
       while(!(completa(aux))){
           for(int i=0; i<9; i++){
               for(int j=0; j<9; j++){
                   if (aux[i][j] == 0){
                       solution = soluciones(aux, i, j);
                       if (solution.size() == 1){ // SI la solucion es unica, la pongo en la casilla (i,j)
                           aux[i][j] = solution.get(0);
                       }
                   }
               }
           }
       }
       return aux;
   }
   
   
}
    
